{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using Flash Attention 2 ⚡"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this notebook we will compare [Flash Attention 2](https://github.com/Dao-AILab/flash-attention) with the [`torch.nn.functional.scaled_dot_product_attention`](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) function and a simple implementation."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Installation\n",
    "\n",
    "Follow instructions here:\n",
    "https://github.com/Dao-AILab/flash-attention"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Uncomment the following line to install the package from PyPI\n",
    "## You may need to restart the runtime in Colab after this\n",
    "## Remember to choose a GPU runtime for faster training!\n",
    "\n",
    "# !pip install rl4co"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/botu/.local/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import torch.utils.benchmark as benchmark\n",
    "\n",
    "\n",
    "# Simple implementation in PyTorch\n",
    "from rl4co.models.nn.attention import scaled_dot_product_attention_simple\n",
    "# PyTorch official implementation of FlashAttention 1\n",
    "from torch.nn.functional import scaled_dot_product_attention\n",
    "# FlashAttention 2\n",
    "from rl4co.models.nn.flash_attention import scaled_dot_product_attention_flash_attn\n",
    "\n",
    "from rl4co.envs import TSPEnv\n",
    "from rl4co.models.zoo.am import AttentionModel\n",
    "from rl4co.utils.trainer import RL4COTrainer\n",
    "from rl4co.models.common.constructive.autoregressive import GraphAttentionEncoder\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Testing differences with simple tensors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n",
      "tensor(0.0005, device='cuda:0', dtype=torch.float16) tensor(1.2159e-05, device='cuda:0', dtype=torch.float16)\n",
      "tensor(0.0005, device='cuda:0', dtype=torch.float16) tensor(6.3777e-06, device='cuda:0', dtype=torch.float16)\n"
     ]
    }
   ],
   "source": [
    "bs, head, length, d = 64, 8, 512, 128\n",
    "\n",
    "query = torch.rand(bs, head, length, d, dtype=torch.float16, device=\"cuda\")\n",
    "key = torch.rand(bs, head, length, d, dtype=torch.float16, device=\"cuda\")\n",
    "value = torch.rand(bs, head, length, d, dtype=torch.float16, device=\"cuda\")\n",
    "\n",
    "# Simple implementation in PyTorch\n",
    "out_simple = scaled_dot_product_attention_simple(query, key, value)\n",
    "\n",
    "# PyTorch official implementation of FlashAttention 1\n",
    "out_pytorch = scaled_dot_product_attention(query, key, value)\n",
    "\n",
    "# FlashAttention 2\n",
    "out_flash_attn = scaled_dot_product_attention_flash_attn(query, key, value)\n",
    "\n",
    "\n",
    "print(torch.allclose(out_simple, out_pytorch, atol=1e-3))\n",
    "print(torch.allclose(out_flash_attn, out_pytorch, atol=1e-3))\n",
    "\n",
    "print(torch.max(torch.abs(out_simple - out_pytorch)), torch.mean(torch.abs(out_simple - out_pytorch)))\n",
    "print(torch.max(torch.abs(out_flash_attn - out_pytorch)), torch.mean(torch.abs(out_flash_attn - out_pytorch)))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Testing Graph Attention Encoders with Flash Attention 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GraphAttentionEncoder(\n",
       "  (init_embedding): TSPInitEmbedding(\n",
       "    (init_embed): Linear(in_features=2, out_features=128, bias=True)\n",
       "  )\n",
       "  (net): GraphAttentionNetwork(\n",
       "    (layers): Sequential(\n",
       "      (0): MultiHeadAttentionLayer(\n",
       "        (0): SkipConnection(\n",
       "          (module): MultiHeadAttention(\n",
       "            (Wqkv): Linear(in_features=128, out_features=384, bias=True)\n",
       "            (out_proj): Linear(in_features=128, out_features=128, bias=True)\n",
       "          )\n",
       "        )\n",
       "        (1): Normalization(\n",
       "          (normalizer): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "        (2): SkipConnection(\n",
       "          (module): Sequential(\n",
       "            (0): Linear(in_features=128, out_features=512, bias=True)\n",
       "            (1): ReLU()\n",
       "            (2): Linear(in_features=512, out_features=128, bias=True)\n",
       "          )\n",
       "        )\n",
       "        (3): Normalization(\n",
       "          (normalizer): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (1): MultiHeadAttentionLayer(\n",
       "        (0): SkipConnection(\n",
       "          (module): MultiHeadAttention(\n",
       "            (Wqkv): Linear(in_features=128, out_features=384, bias=True)\n",
       "            (out_proj): Linear(in_features=128, out_features=128, bias=True)\n",
       "          )\n",
       "        )\n",
       "        (1): Normalization(\n",
       "          (normalizer): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "        (2): SkipConnection(\n",
       "          (module): Sequential(\n",
       "            (0): Linear(in_features=128, out_features=512, bias=True)\n",
       "            (1): ReLU()\n",
       "            (2): Linear(in_features=512, out_features=128, bias=True)\n",
       "          )\n",
       "        )\n",
       "        (3): Normalization(\n",
       "          (normalizer): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (2): MultiHeadAttentionLayer(\n",
       "        (0): SkipConnection(\n",
       "          (module): MultiHeadAttention(\n",
       "            (Wqkv): Linear(in_features=128, out_features=384, bias=True)\n",
       "            (out_proj): Linear(in_features=128, out_features=128, bias=True)\n",
       "          )\n",
       "        )\n",
       "        (1): Normalization(\n",
       "          (normalizer): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "        (2): SkipConnection(\n",
       "          (module): Sequential(\n",
       "            (0): Linear(in_features=128, out_features=512, bias=True)\n",
       "            (1): ReLU()\n",
       "            (2): Linear(in_features=512, out_features=128, bias=True)\n",
       "          )\n",
       "        )\n",
       "        (3): Normalization(\n",
       "          (normalizer): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "    )\n",
       "  )\n",
       ")"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "env = TSPEnv(generator_params=dict(num_loc=1000))\n",
    "\n",
    "num_heads = 8\n",
    "embed_dim = 128\n",
    "num_layers = 3\n",
    "enc_simple = GraphAttentionEncoder(env, num_heads=num_heads, embed_dim=embed_dim, num_layers=num_layers,\n",
    "                            sdpa_fn=scaled_dot_product_attention_simple)\n",
    "\n",
    "enc_fa1 = GraphAttentionEncoder(env, num_heads=num_heads, embed_dim=embed_dim, num_layers=num_layers,\n",
    "                            sdpa_fn=scaled_dot_product_attention)\n",
    "\n",
    "enc_fa2 = GraphAttentionEncoder(env, num_heads=num_heads, embed_dim=embed_dim, num_layers=num_layers,\n",
    "                            sdpa_fn=scaled_dot_product_attention_flash_attn)\n",
    "\n",
    "# Flash Attention supports only FP16 and BFloat16\n",
    "enc_simple.to(\"cuda\").half()\n",
    "enc_fa1.to(\"cuda\").half()\n",
    "enc_fa2.to(\"cuda\").half()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_models(num_heads=8, embed_dim=128, num_layers=3):\n",
    "    enc_simple = GraphAttentionEncoder(env, num_heads=num_heads, embed_dim=embed_dim, num_layers=num_layers,\n",
    "                                sdpa_fn=scaled_dot_product_attention_simple)\n",
    "\n",
    "    enc_fa1 = GraphAttentionEncoder(env, num_heads=num_heads, embed_dim=embed_dim, num_layers=num_layers,\n",
    "                                sdpa_fn=scaled_dot_product_attention)\n",
    "\n",
    "    enc_fa2 = GraphAttentionEncoder(env, num_heads=num_heads, embed_dim=embed_dim, num_layers=num_layers,\n",
    "                                sdpa_fn=scaled_dot_product_attention_flash_attn)\n",
    "\n",
    "    # Flash Attention supports only FP16 and BFloat16\n",
    "    enc_simple.to(\"cuda\").half()\n",
    "    enc_fa1.to(\"cuda\").half()\n",
    "    enc_fa2.to(\"cuda\").half()\n",
    "    return enc_simple, enc_fa1, enc_fa2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Times for problem size 10: Simple 0.633, FA1 0.511, FA2 0.554\n",
      "Times for problem size 20: Simple 0.646, FA1 0.535, FA2 0.565\n",
      "Times for problem size 50: Simple 0.663, FA1 0.547, FA2 0.580\n",
      "Times for problem size 100: Simple 0.664, FA1 0.547, FA2 0.580\n",
      "Times for problem size 200: Simple 0.670, FA1 0.509, FA2 0.585\n",
      "Times for problem size 500: Simple 0.669, FA1 0.512, FA2 0.582\n",
      "Times for problem size 1000: Simple 1.088, FA1 0.555, FA2 0.609\n",
      "Times for problem size 2000: Simple 3.626, FA1 1.292, FA2 0.790\n",
      "Times for problem size 5000: Simple 20.332, FA1 5.748, FA2 2.943\n",
      "Times for problem size 10000: Simple 80.337, FA1 20.701, FA2 10.230\n"
     ]
    }
   ],
   "source": [
    "threads = 32\n",
    "sizes = [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000]\n",
    "\n",
    "times_simple = []\n",
    "times_fa1 = []\n",
    "times_fa2 = []\n",
    "\n",
    "# for embed_dim in [64, 128, 256]:\n",
    "for embed_dim in [128]:\n",
    "    # Get models\n",
    "    enc_simple, enc_fa1, enc_fa2 = build_models(embed_dim=embed_dim)\n",
    "\n",
    "    for problem_size in sizes:\n",
    "\n",
    "        with torch.no_grad():\n",
    "            # initial data\n",
    "            env = TSPEnv(generator_params=dict(num_loc=problem_size))\n",
    "            td_init = env.reset(batch_size=[2])\n",
    "            # set dtype to float16\n",
    "            td_init = td_init.to(dest=\"cuda\", dtype=torch.float16)\n",
    "\n",
    "            t_simple = benchmark.Timer(\n",
    "                setup='x = td_init',\n",
    "                stmt='encode(x)',\n",
    "                globals={'td_init': td_init, 'encode': enc_simple},\n",
    "                num_threads=threads)\n",
    "\n",
    "            t_fa1 = benchmark.Timer(\n",
    "                setup='x = td_init',\n",
    "                stmt='encode(x)',\n",
    "                globals={'td_init': td_init, 'encode': enc_fa1},\n",
    "                num_threads=threads)\n",
    "            \n",
    "            t_fa2 = benchmark.Timer(\n",
    "                setup='x = td_init',\n",
    "                stmt='encode(x)',\n",
    "                globals={'td_init': td_init, 'encode': enc_fa2},\n",
    "                num_threads=threads)\n",
    "            \n",
    "            times_simple.append(torch.tensor(t_simple.blocked_autorange().times).mean())\n",
    "            times_fa2.append(torch.tensor(t_fa2.blocked_autorange().times).mean())\n",
    "            times_fa1.append(torch.tensor(t_fa1.blocked_autorange().times).mean())\n",
    "\n",
    "            print(f\"Times for problem size {problem_size}: Simple {times_simple[-1]*1e3:.3f}, FA1 {times_fa1[-1]*1e3:.3f}, FA2 {times_fa2[-1]*1e3:.3f}\")\n",
    "\n",
    "    # eliminate cache\n",
    "    torch.cuda.empty_cache()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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119/HZ/73Oei+nzNNdfgtddeG1PHOANGRES5x5BFRER55XQ60dDQkHL5K664Aps3b8bAwEAkgO3duxeqqkZujAGEZnp8Pl/kbn3vvfceSkpKUFdXN6bNRYsWQQiBc+fO4YYbbpjkESU3f/58zJ8/H9/61rewevVqbNq0KW7Iam9vx6pVq/C9730PK1eujNr2+c9/Hm+88QZmzZoFl8uV9T4TEVHqeHdBIiIqKmvWrIHNZsN9992HDz74IDLTc88990QuFQRCt3tfu3Ytjh49im3btmHDhg1Yv379mM9jAaHQs2bNGtx777344x//iBMnTuD999/Hj3/8Y7z11lsZ67vP58P69euxa9cunDx5Env37kVrayuuuOKKuGWXL1+ORYsWYd26dejq6oo8wudhxowZuO2227Bnzx6cOHECu3btwiOPPILTp09nrM9ERJQ+zmQREVFRcTgceOedd/Doo4+iqakJDocDd9xxB1544YWocrfccgsaGxtx4403wu/3Y/Xq1VGf9Yq1adMmPP300/jOd76DM2fOYMaMGfjCF76Ar3zlKxnru6ZpuHjxIu699150d3djxowZWLlyJZ588skxZbu7u/HRRx/ho48+ityMI0xKCYfDgd27d+OJJ57AypUr0d/fj9raWtxyyy2c2SIiyjNFSinz3QkiIiIiIqKpgpcLEhERERERZRBDFhERERERUQYxZBEREREREWUQQxYREREREVEGMWQRERERERFlEEMWERERERFRBjFkERERERERZRBDFhERERERUQYxZBEREREREWUQQxYREREREVEGMWQRERERERFl0P8Cm3MBR/mgg4sAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot results\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "\n",
    "fig, ax = plt.subplots(1, 1, figsize=(10, 5))\n",
    "ax.plot(sizes, times_simple, label=\"Simple\")\n",
    "ax.plot(sizes, times_fa1, label=\"FlashAttention 1\")\n",
    "ax.plot(sizes, times_fa2, label=\"FlashAttention 2\")\n",
    "\n",
    "# fancy grid\n",
    "ax.grid(True, which=\"both\", ls=\"-\", alpha=0.5)\n",
    "ax.set_xscale(\"log\")\n",
    "ax.set_yscale(\"log\")\n",
    "ax.set_xlabel(\"Problem size\")\n",
    "ax.set_ylabel(\"Time (ms)\")\n",
    "ax.legend()\n",
    "\n",
    "# Instead of 10^1, 10^2... show nuber\n",
    "ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f\"{x:.0f}\"))\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using FlashAttention can speed up inference even at small context lengths (number of nodes in the graph). Difference can be of several times for large graphs between different implementations!"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "env",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
